import { LabelActor, Mesh, VTActor, VTActorRenderType } from "cax-base";
import type { FrontProcessing } from "@/FrontProcessing/index";
import { TFace } from "@/FrontProcessing/Actors/TFace";
import { TMeshPoint, TPoint } from "@/FrontProcessing/Actors/TMeshPoint";
import { MeshActor } from "@/FrontProcessing/Actors/MeshActor";

export class MeshComp {
  engine: FrontProcessing;
  renderer: any;
  // * 索引为partId 值为网格对象
  meshActorMap: Map<number, VTActor> = new Map();
  meshPointActorMap: Map<number, VTActor> = new Map();
  nodeId2label = new Map<number, LabelActor>();

  constructor(engine: FrontProcessing) {
    this.engine = engine;
    this.renderer = engine.system?.app.renderer;
  }

  // * 需要把被选中的partId和网格id都返回回来，需要merge的网格。
  // * 如果一个MeshActor中含有超过两个以上被选中cell，发出alert，并返回空结果。
  getMergePartIdCellIds(): number[] {
    let hasSelected = false;
    const partIdCellIds: number[] = [];
    this.meshActorMap.forEach((value, key) => {
      if (value instanceof MeshActor && value.isDpMesh == false) {
        const cellIds = value.getSelectedCellIds();
        if (cellIds.size != 2 && cellIds.size != 0) {
          alert("请选择两个网格进行合并！");
          return [];
        }
        if (hasSelected) {
          alert("只能一次选择两个网格进行合并");
          return [];
        }
        partIdCellIds.push(key);
        cellIds.forEach((id) => {
          partIdCellIds.push(id);
        });
        hasSelected = true;
      }
    });
    return partIdCellIds;
  }

  // * 更新网格 限制 mesh 类型
  updateMesh(mesh: MeshActor, partId: number) {
    if (!this.meshActorMap.has(partId)) {
      this.addMesh(mesh, partId);
    } else {
      const oldMesh = this.meshActorMap.get(partId);
      if (oldMesh) {
        if (oldMesh instanceof MeshActor && oldMesh.isDpMesh == false) {
          oldMesh.removeCellIds();
        }
        this.engine.model.remove(oldMesh);
        this.addMesh(mesh, partId);
      }
    }
  }
  // * 更新网格交叉点 限制 mesh point 类型
  updateMeshPoint(meshPoint: TMeshPoint, partId: number) {
    if (!this.meshPointActorMap.has(partId)) {
      this.addMeshPoint(meshPoint, partId);
    } else {
      const oldMeshPoint = this.meshPointActorMap.get(partId);
      if (oldMeshPoint) {
        this.engine.model.remove(oldMeshPoint);
        this.addMeshPoint(meshPoint, partId);
      }
    }
  }

  // * 清除网格
  clearMesh() {
    this.meshActorMap.forEach((value) => {
      this.engine.model.remove(value);
      (value as MeshActor).unselectAllElements();
    });
    this.meshActorMap.clear();
  }
  // delete dp mesh
  deleteDpMesh() {
    this.meshActorMap.forEach((value) => {
      if (value instanceof MeshActor && value.isDpMesh == true) {
        this.engine.model.remove(value);
      }
    });
  }
  // * 取消选中所有元素
  unselectAllElements() {
    this.meshActorMap.forEach((value) => {
      (value as MeshActor).unselectAllElements();
    });
  }
  // * 添加网格
  addMesh(mesh: VTActor, partId: number) {
    this.meshActorMap.set(partId, mesh);
    this.engine.model.add(mesh);
  }
  // * 添加网格交叉点 初始化add不添加网格交叉点，只记录其信息
  addMeshPoint(meshPoint: TMeshPoint, partId: number) {
    this.meshPointActorMap.set(partId, meshPoint);
  }
  // 格宇mesh --> Actor
  gyMeshToActor(
    data: string,
    lineWidth: number,
    color: any,
    isDpMesh: boolean
  ) {
    const k = JSON.parse(data);
    const face = new TFace();
    face.parseForGy(k);
    const meshActor = new MeshActor(face, lineWidth, color, isDpMesh);
    console.log(meshActor);
    meshActor.isMesh = true;
    // const meshPointActor = new TMeshPoint(face);
    // meshPointActor.isMeshPoint = true;
    return { meshActor: meshActor };
  }
  // 网格节点重新编号
  renumberingCellIds(formModel: any) {
    const param = Object.assign({}, formModel);
    param.nodesInfo = this.engine.selectBoxComp.selectedPoints.map((e) => {
      return {
        partId: e.partId,
        nodeId: e.nodeId,
      };
    });
    this.selectMeshPointByClick(this.engine.selectBoxComp.selectedPoints);
    this.nodeId2label.forEach((value) => {
      this.engine?.system?.parent?.model.remove(value);
    });
    return new Promise((resolve) => {
      // eslint-disable-next-line @typescript-eslint/no-empty-function
      this.engine.cell.re_number(param).then(() => {});
    });
  }
  // 显示被选中网格编号
  showSelectedCellIds() {
    this.meshActorMap.forEach((value) => {
      if (value instanceof MeshActor && value.isDpMesh == false) {
        value.showCellIds();
      }
    });
  }
  showSelectedNodeIds() {
    this.engine.selectBoxComp.selectedPoints.forEach((node) => {
      const nodeLabel = new LabelActor([node.x, node.y, node.z], {
        text: node.nodeId.toString(),
      });
      this.engine?.system?.parent?.model.add(nodeLabel);
      this.nodeId2label.set(node.nodeId, nodeLabel);
    });
  }

  // 隐藏被选中网格节点编号
  hindSeletedCellIds() {
    this.meshActorMap.forEach((value) => {
      if (value instanceof MeshActor && value.isDpMesh == false) {
        value.removeCellIds();
      }
    });
  }

  // 通过框选选中元素
  selectElementsByBox(
    x: number,
    y: number,
    width: number,
    height: number,
    containerHeight: number
  ) {
    this.meshActorMap.forEach((value) => {
      if (value instanceof MeshActor && value.isDpMesh == false) {
        value.selectElementsByBox(
          x,
          y,
          width,
          height,
          containerHeight,
          this.renderer,
          this.engine
        );
      }
    });
  }
  // 通过框选选中mesh point
  selectMeshPointByBox(
    x: number,
    y: number,
    width: number,
    height: number,
    containerHeight: number
  ) {
    this.meshActorMap.forEach((value) => {
      if (value instanceof MeshActor && value.isDpMesh == false) {
        value.selectMeshPointByBox(
          x,
          y,
          width,
          height,
          containerHeight,
          this.renderer,
          this.engine
        );
      }
    });
  }
  selectMeshPointByClick(TPointData: TPoint[]) {
    this.meshActorMap.forEach((actor) => {
      if (actor instanceof MeshActor && actor.isDpMesh == false) {
        TPointData.forEach((point) => {
          actor.selectNodeWithDoubleClick(point);
        });
      }
    });
    this.engine.render.render();
  }
}
